#include <boost/foreach.hpp>
#include "FirstLevelDescriptor.h"
#include "Exception.h"
#include "Logger.h"

using namespace game_engine::data_format;

///////////////////////////////////////////////////////////////////////////////
// Constructors and Destructors
///////////////////////////////////////////////////////////////////////////////

FirstLevelDescriptor::FirstLevelDescriptor(void)
    : LevelDescriptor(), tileWorldInfo(), animFilename(), playerInfo()
{
    enemyAList.clear();
    killPowerupList.clear();
    speedPowerupList.clear();
}

FirstLevelDescriptor::~FirstLevelDescriptor(void)
{
}

///////////////////////////////////////////////////////////////////////////////
// Other public methods
///////////////////////////////////////////////////////////////////////////////

void FirstLevelDescriptor::parse(const string &filename)
{
    // FIXME : this is UGLY!! I cannot find the way to parse the file into
    // XmlUtils. It seems to be a problem with the copy constructor of the
    // xml_document template
    // Read all content from input file and store it into a single string
    string fileContent = XmlUtils::readAll(filename);
    // Parse the whole XML file
    XmlDocument doc;
    doc.parse<0>(const_cast<char *>(fileContent.c_str()));

    // Parse screen information
    screenInfo.parse(doc);

    // Parse tile world information
    tileWorldInfo.parse(doc);

    // Parse animation filename
    animFilename = XmlUtils::getString("level_parameters.animations_file", doc);

    // Parse player information
    playerInfo.parse(doc);

    // Parse enemyA information
    string texFilename = XmlUtils::getString(
        "level_parameters.enemyA_list.enemyA_texture_file", doc);
    BOOST_FOREACH(XmlNode *node, XmlUtils::getNodes(
        "level_parameters.enemyA_list.enemyA", doc))
    {
        EnemyAInfo enemyA;
        enemyA.parse(node);
        enemyA.setTextureFilename(texFilename);
        enemyAList.push_back(enemyA);
    }

    // Parse powerup information
    BOOST_FOREACH(XmlNode *node, XmlUtils::getNodes(
        "level_parameters.powerup_list.kill_powerup", doc))
    {
        PowerUpInfo powerUp;
        powerUp.parse(node);
        killPowerupList.push_back(powerUp);
    }

    BOOST_FOREACH(XmlNode *node, XmlUtils::getNodes(
        "level_parameters.powerup_list.speed_powerup", doc))
    {
        PowerUpInfo powerUp;
        powerUp.parse(node);
        speedPowerupList.push_back(powerUp);
    }
}

///////////////////////////////////////////////////////////////////////////////
// Getters
///////////////////////////////////////////////////////////////////////////////

const TileWorldInfo& FirstLevelDescriptor::getTileWorldInfo(void) const
{
    return tileWorldInfo;
}

const string& FirstLevelDescriptor::getAnimFilename(void) const
{
    return animFilename;
}

const PlayerInfo& FirstLevelDescriptor::getPlayerInfo(void) const
{
    return playerInfo;
}

const list<EnemyAInfo>& FirstLevelDescriptor::getEnemyAList(void) const
{
    return enemyAList;
}
